package com.yc.io.niodemo.chat;

import org.springframework.util.StringUtils;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

/**
 * 消息处理类 处理消息的编解码
 *
 * @author samuelchen
 * @version 1.0
 * @date 2022-04-15
 */
public class Message {

    public static final String MSG_SPLIT = "#@@#";
    public static final Charset CHARSET = StandardCharsets.UTF_8;

    private MessageType messageType;
    private String option;
    private String message;

    public Message(MessageType messageType, String option, String message) {
        this.messageType = messageType;
        this.option = option;
        this.message = message;
    }

    public Message(MessageType messageType, String message) {
        this.messageType = messageType;
        this.message = message;
    }

    public ByteBuffer encode() {
        StringBuilder builder = new StringBuilder(messageType.getAction());
        if (option != null && option.length() > 0) {
            builder.append(MSG_SPLIT);
            builder.append(option);
        }
        builder.append(MSG_SPLIT);
        builder.append(message);
        return CHARSET.encode(builder.toString());
    }

    public static Message decode(String message) {
        if (StringUtils.isEmpty(message)) {
            return null;
        }
        String[] messageArr = message.split(MSG_SPLIT);
        MessageType messageType = messageArr.length > 1 ? MessageType.getActionType(messageArr[0]) : null;

        switch (messageArr.length) {
            case 2:
                return new Message(messageType, messageArr[1]);
            case 3:
                return new Message(messageType, messageArr[1], messageArr[2]);
            default:
                return null;
        }
    }

    public static ByteBuffer encodeRegsyn() {
        return encodeRegsyn(false);
    }

    public static ByteBuffer encodeRegsyn(boolean duplicate) {
        MessageType action = MessageType.REG_SERVER_SYN;
        String message = "please input your name to register";
        if (duplicate) {
            message = "this name is used, Please input another name";
        }
        return new Message(action, message).encode();
    }

    public static ByteBuffer encodeSendMsg(String msg) {
        return encodeSendMsg(null, msg);
    }

    public static ByteBuffer encodeSendMsg(String toUser, String msg) {
        MessageType chatMsgSend = MessageType.CHAT_MSG_SEND;
        return new Message(chatMsgSend, toUser, msg).encode();
    }

    public static ByteBuffer encodeReceiveMsg(String fromUser, String msg) {
        MessageType chatMsgReceive = MessageType.CHAT_MSG_RECEIVE;
        return new Message(chatMsgReceive, fromUser, msg).encode();
    }

    public static ByteBuffer encodeRegClientAck(String username) {
        MessageType regClientAck = MessageType.REG_CLIENT_ACK;
        return new Message(regClientAck, username).encode();
    }

    public static ByteBuffer encodeRegServerAck(String username) {
        MessageType regServerAck = MessageType.REG_SERVER_ACK;
        String message = username +  ", Welcome to join the chat";
        return new Message(regServerAck, message).encode();
    }

    public static ByteBuffer encodePublishUserList(List<String> userList) {
        MessageType broadcastUserListAction = MessageType.BROADCAST_USER_LIST;
        String message = Arrays.toString(userList.toArray());
        return new Message(broadcastUserListAction, message).encode();
    }

    public MessageType getMessageType() {
        return messageType;
    }

    public void setMessageType(MessageType messageType) {
        this.messageType = messageType;
    }

    public String getOption() {
        return option;
    }

    public void setOption(String option) {
        this.option = option;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
